iT邦幫忙

2024 iThome 鐵人賽

DAY 8
0
Software Development

我命由我不由語言 java爬蟲挑戰系列 第 8

java爬蟲挑戰 Day 8 - 使用Jsoup解析物件 (1)

  • 分享至 

  • xImage
  •  

Jsoup可以將字串轉成HTML的DOM物件,方便我們取得資料。

Document doc = Jsoup.parse(pageSource);

之後提取必要資訊,存入我們的Java物件中,進行後續處裡即可。

抓取DOM的資料

DOM就是將HTML的文字轉化為階層式的樹狀結構,所以想要提取資訊必須先對HTML有一定的認知。
不過我這邊就不說明了,有興趣的自己去學習一下。

那我們要如何提取資料?

使用Chrome的F12 之後按Ctrl+Shift+C 選取想要的物件

https://ithelp.ithome.com.tw/upload/images/20240825/20168635pHNdEZp3Xm.png

可以看到我們想要的資訊都在class="item-info"的Div裡面
之後就可以使用Jsoup的選擇器提取資料即可


以上是三年前的做法

現在使用GPT提取資料:

https://ithelp.ithome.com.tw/upload/images/20240825/20168635rKPe2warYQ.png

程式碼部分

private void parseHTML(Document doc) {
    Elements listings = doc.select("div.item-info");

    // 迴圈遍歷每個房源資訊
    for (Element listing : listings) {
        // 提取標題
        String title = listing.select("a.link").attr("title");
        // 提取連結
        String link = listing.select("a.link").attr("href");
        // 提取地址
        String address = listing.select("div.item-info-txt i.house-place").next().text();
        // 提取價格
        String price = listing.select("div.item-info-price strong").text();
        // 提取樓層與坪數
        String floorAndArea = listing.select("div.item-info-txt").get(1).text();
        // 提取距離捷運
        String distanceToMRT = listing.select("div.item-info-txt i.house-metro").next().text();
        
        // 輸出房源資訊
        log.info("Title: {}", title);
        log.info("Link: {}", link);
        log.info("Address: {}", address);
        log.info("Price: {} 元/月", price);
        log.info("Floor and Area: {}", floorAndArea);
        log.info("Distance to MRT: {}", distanceToMRT);
        log.info("---------------------------------------");
    }
}

log如下:
https://ithelp.ithome.com.tw/upload/images/20240825/20168635VHhWAzL0kq.png

資訊不完整的挑戰

在這次的資料抓取過程中,我發現了資料不完整的問題。仔細檢查後,我注意到以下幾點:

  • 樓層資訊缺失:有些房源沒有提供樓層資訊,這使得樓層與坪數的數據不全。
  • 距離捷運站的資訊不一致:部分房源沒有標示距離捷運站的距離,而是標示了距離公車站的距離。
  • 建案、社區、大樓資訊:有些房源屬於某個建案、社區或大樓,導致其資訊格式與預期不同。
  • 資訊過少: 需求分析階段期望獲得的資訊無法完全抓取到。

解決方案

在點擊進入每個房源的詳細頁面後,進行第二次資料爬取,這樣可以獲取到更完整、詳細的資訊。

不過這部分明天再處理了。

將資訊存入物件

接著為了後續開發方便,先將剛剛的資訊寫入物件中。
且我有使用lombok來簡化程式碼,所以進行以下改動。

pom.xml

<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<version>1.18.34</version>
	<scope>provided</scope>
</dependency>

RentalListing.java

@Data
public class RentalListing {
    private String title;
    private String link;
    private String address;
    private String price;
    private String floorAndArea;
    private String distanceToMRT;
}

RentalCrawlerServiceImpl.java -parseHTML(Document doc)

RentalListing rentalList = new RentalListing();
rentalList.setTitle(title);
rentalList.setLink(link);
rentalList.setAddress(address);
rentalList.setPrice(price);
rentalList.setFloorAndArea(floorAndArea);
rentalList.setDistanceToMRT(distanceToMrtName+distanceToMRT);

git 狀態

程式碼太亂了,我先進行了重構。
這部分就只放在git上了。
https://ithelp.ithome.com.tw/upload/images/20240825/20168635havf7eed4G.png


上一篇
java爬蟲挑戰 Day 7 - 使用selenium處理動態網頁
下一篇
java爬蟲挑戰 Day 9 - 使用Jsoup解析物件 (2)
系列文
我命由我不由語言 java爬蟲挑戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言